package co.edu.udea.iw.prestamos.ws;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import co.edu.udea.iw.prestamos.bl.PrestamoBL;
import co.edu.udea.iw.prestamos.modelo.dto.Prestamo;
import co.edu.udea.iw.prestamos.modelo.dto.Respuesta;
import co.edu.udea.iw.prestamos.util.seguridad.Autorizacion;

/**
 * Recurso para administrar los Prestamos
 * 
 * @author Dave Rivera <daverivera90@gmail.com>
 * @since 12-07-2014
 * @version 1.0
 */
@Path("prestamos")
@Component
@Transactional
public class PrestamoResource {
	
	@Autowired
	private Autorizacion autorizacion;
	
	@Autowired
	private PrestamoBL prestamoBL;

	/**
	 * Permite obtener todas las solicitudes. 
	 * 
	 * Este recurso es accesible solo por los Admin.
	 * 
	 * Asociado al RF-002
	 * 
	 * @param prestamo Solicitud del prestamo del dispositivo
	 * @return {@link Respuesta} indicando si hubo algun error en la transaccion o si se realizó el prestamo correctamente
	 */
	@GET
	@Produces({MediaType.APPLICATION_JSON})
	public Object obtenerPrestamos(@HeaderParam("user")  String username, 
					               @HeaderParam("role")  String rol,
					               @HeaderParam("token") String token){
		
		Set<String> roles = new HashSet<String>() {{ add(Autorizacion.ROLE_ADMIN); }};
		if( autorizacion.isNotAuthorized(roles, username, rol) )
			throw new WebApplicationException(Response.Status.FORBIDDEN);
		
		return prestamoBL.obtenerSolicitudes();
	}
	
	/**
	 * Permite realizar la solicitud de un prestamo. 
	 * 
	 * Este recurso es accesible solo por los Investigadores.
	 * 
	 * Asociado al RF-001.
	 * 
	 * @param prestamo Solicitud del prestamo del dispositivo
	 * @return {@link Respuesta} indicando si hubo algun error en la transaccion o si se realizó el prestamo correctamente
	 */
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public Object registrarPrestamo(@HeaderParam("user")  String username, 
						            @HeaderParam("role")  String rol,
						            @HeaderParam("token") String token,
						            Prestamo prestamo){
		
		Set<String> roles = new HashSet<String>() {{ add(Autorizacion.ROLE_INVESTIGADOR); }};
		if( autorizacion.isNotAuthorized(roles, username, rol) )
			throw new WebApplicationException(Response.Status.FORBIDDEN);
		
		return prestamoBL.realizarPrestamo(prestamo);
	}
	
	/**
	 * Permite aprobar o rechazar la solicitud de un prestamo. 
	 * 
	 * Este recurso es accesible solo por los Admin.
	 * 
	 * Asociado al RF-002, RF-021
	 * 
	 * @param prestamo Solicitud del prestamo del dispositivo
	 * @return {@link Respuesta} indicando si hubo algun error en la transaccion o si se realizó el prestamo correctamente
	 */
	@PUT
	@Path("{id}/estado/{estado}")
	public Object cambiarEstado(@PathParam("id")int id, 
								@PathParam("estado") int idEstado,
								@HeaderParam("user")  String username, 
					            @HeaderParam("role")  String rol,
					            @HeaderParam("token") String token){
		
		Set<String> roles = new HashSet<String>() {{ add(Autorizacion.ROLE_ADMIN); }};
		if( autorizacion.isNotAuthorized(roles, username, rol) )
			throw new WebApplicationException(Response.Status.FORBIDDEN);
		
		return prestamoBL.cambiarEstado(id, idEstado);
	}
	
	/**
	 * Permite obtener los prestamos realizados por un usuario. 
	 * 
	 * Este recurso es accesible solo por los Investigadores.
	 * 
	 * Asociado al RF-002, RF-021
	 * 
	 * @param prestamo Solicitud del prestamo del dispositivo
	 * @return {@link Respuesta} indicando si hubo algun error en la transaccion o si se realizó el prestamo correctamente
	 */
	@GET
	@Path("usuario/{cedula}")
	@Produces({MediaType.APPLICATION_JSON})
	public Object obtenerPrestamosInvestigador(@PathParam("cedula") String cedula,
											   @HeaderParam("user")  String username, 
									           @HeaderParam("role")  String rol,
									           @HeaderParam("token") String token) {
		
		Set<String> roles = new HashSet<String>() {{ add(Autorizacion.ROLE_INVESTIGADOR); }};
		if( autorizacion.isNotAuthorized(roles, username, rol) )
			throw new WebApplicationException(Response.Status.FORBIDDEN);
		
		return prestamoBL.obtenerSolicitudes();
	}
	
	/**
	 * Permite obtener un prestamo en especifico. 
	 * 
	 * Este recurso es accesible por los Investigadores y Admin.
	 * 
	 * Asociado al RF-002, RF-021
	 * 
	 * @param prestamo Solicitud del prestamo del dispositivo
	 * @return {@link Respuesta} indicando si hubo algun error en la transaccion o si se realizó el prestamo correctamente
	 */
	@GET
	@Path("{id}")
	@Produces({MediaType.APPLICATION_JSON})
	public Object obtenerPrestamo(@PathParam("id") int id,
								  @HeaderParam("user")  String username, 
						          @HeaderParam("role")  String rol,
						          @HeaderParam("token") String token) {
		
		Set<String> roles = new HashSet<String>() {{ add(Autorizacion.ROLE_INVESTIGADOR); add(Autorizacion.ROLE_ADMIN); }};
		if( autorizacion.isNotAuthorized(roles, username, rol) )
			throw new WebApplicationException(Response.Status.FORBIDDEN);
		
		return prestamoBL.obtenerPrestamo(id);
	}
}
